import { defineStore } from 'pinia';
import { ElMessage } from 'element-plus';
import type { RouteRecordRaw } from 'vue-router';
import type { RoutesFace } from '@/api/types/user';
// 权限路由表
import permissionrRoutes from '@/router/permissionModules/index';
// 本地无需权限路由表
import constantModules from '@/router/constantModules/index';
import { getRoutes } from '@/api/user';
import { isObject } from '@/utils/auth';
import { allDetailsRoutes } from '@/router/detailsModules';
import { resetRouter } from '@/router';
/**
 * @description:本地路由是否有权限
 * @param {string} asyncRoute 后台返回的路由表的路由
 * @param {any} permissionrRoutes  本地权限路由表
 * @return {*}
 */

function hasPermission(
    asyncRoute: RoutesFace | RouteRecordRaw,
    permissionrRoutes: Array<RouteRecordRaw>
): boolean {
    let hasRoute = false;
    const stack: Array<RouteRecordRaw> = [...permissionrRoutes];
    let permissionRoute: RouteRecordRaw | undefined;

    while ((permissionRoute = stack.shift()) && !hasRoute) {
        hasRoute = permissionRoute.name === asyncRoute.name;
        if (hasRoute) {
            //将本地的路由信息同步更新到后台的路由表 以后台的顺序以及字段为主 包括path redirect 等字段
            Object.keys(permissionRoute).forEach((name) => {
                //断言key
                const key = name as keyof typeof permissionRoute;
                //如果key不为children（会接着遍历所以避开） 且后台路由key不存在的话
                if (key == 'children' || key == 'redirect') {
                    return;
                }
                if (!asyncRoute[key]) {
                    asyncRoute[key] = permissionRoute![key];
                } else if (isObject(asyncRoute[key])) {
                    // 如果后台路由key且值为object存在的话 合并
                    asyncRoute[key] = Object.assign(permissionRoute![key], asyncRoute[key]);
                }
            });
        }
        permissionRoute.children && stack.unshift(...permissionRoute.children);
    }

    return hasRoute;
}
/**
 * @description: 过滤出所有有权限的路由菜单(不含详情)
 * @param {Array} permissionrRoutes 本地所有权限路由表
 * @param {any} asyncRoutes 后台返回的路由表
 * @return {*}
 */
export function filterAsyncRoutes(
    permissionrRoutes: Array<RouteRecordRaw>,
    asyncRoutes: Array<RoutesFace>
): any {
    const res: Array<RouteRecordRaw> = [];
    asyncRoutes.forEach((route) => {
        const tmp = { ...route };
        if (hasPermission(tmp, permissionrRoutes)) {
            if (tmp.children) {
                tmp.children = filterAsyncRoutes(permissionrRoutes, tmp.children);
            }
            res.push(tmp as RouteRecordRaw);
        }
    });
    return res;
}

/**
 * @description:  过滤完整好的路由
 * @return {*} res 过滤出所有有权限的路由菜单(不含详情)
 * @return {*} allDetailsRoutes 所有详情
 */
export function getAsyncAllRoutes(
    res: Array<RouteRecordRaw>,
    allDetailsRoutes: Array<RouteRecordRaw>
) {
    const stack: Array<RouteRecordRaw> = [...res];
    let permissionRoute: RouteRecordRaw | undefined;
    while ((permissionRoute = stack.shift())) {
        const addDetailRoutes: Array<RouteRecordRaw> = [];
        // 设置重定向路由
        if (permissionRoute.children && permissionRoute.children.length > 0) {
            permissionRoute.redirect =
                permissionRoute.redirect ||
                resolovePath(permissionRoute.path, permissionRoute.children[0].path);
        }
        // 添加对应的详情路由
        permissionRoute?.children?.forEach((i) => {
            const r = allDetailsRoutes.filter((item) => item?.meta?.activeMenu === i.path) || [];
            addDetailRoutes.push(...r);
        });
        addDetailRoutes.length > 0 && permissionRoute?.children?.push(...addDetailRoutes);

        permissionRoute.children && stack.unshift(...permissionRoute.children);
    }
    return res;
}
/**
 * @description:
 * @param {string} basePath 上一级路由（相对子节点）
 * @param {string} path 子节点当前第一个路由路由
 * @return {*} 拼接重定向路由
 */
export function resolovePath(basePath: string, path: string) {
    if (path.slice(0, 1) == '/') {
        return path;
    } else {
        return `${basePath}/${path}`;
    }
}
export const useAsyncRoutes = defineStore('asyncRoutes', {
    state: () => {
        return {
            // 所有路由
            dynamicRoutes: [] as Array<RouteRecordRaw>,
            //权限路由
            addRoutes: [] as Array<RouteRecordRaw>
        };
    },
    actions: {
        setRoleRoutes() {
            return new Promise((resolve, reject) => {
                getRoutes()
                    .then((res) => {
                        const asyncRoutes = res.data?.routes || [];
                        if (asyncRoutes.length === 0) {
                            //代表接口返回无路由信息
                            reject(res);
                        } else {
                            this.addRoutes = getAsyncAllRoutes(
                                filterAsyncRoutes(permissionrRoutes, asyncRoutes),
                                allDetailsRoutes
                            );
                            this.dynamicRoutes = [...constantModules, ...this.addRoutes];
                            if (this.addRoutes.length == 0) {
                                reject({ err: '无对应路由权限' });
                            } else {
                                resolve(this.addRoutes);
                            }
                        }
                    })
                    .catch((err) => {
                        reject(err);
                    });
            });
        },
        resetAllRoutes() {
            this.addRoutes = [];
            resetRouter();
        }
    }
});
